Skip to content

[pull] master from ruby:master#1038

Merged
pull[bot] merged 11 commits into
turkdevops:masterfrom
ruby:master
May 22, 2026
Merged

[pull] master from ruby:master#1038
pull[bot] merged 11 commits into
turkdevops:masterfrom
ruby:master

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented May 22, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

tekknolagi and others added 11 commits May 21, 2026 10:55
Go from `ModuleExact[VALUE(0x1008)]` to `ModuleExact[Enumerable@0x1008]` if the module's name isn't `nil`.
Also plumb through a `SideExitReason` because the falsy fold to
`SideExit` requires one.
Previously, local indices greater than 255 were truncated when
converted to RegOpnd::Local. This could make a high-index local alias
a tracked low-index local in the register mapping and produce incorrect
values after compilation.

Cap overflowing indices to MAX_CTX_LOCALS. RegMapping treats that index
as untrackable because it is just outside the tracked local range.

Fixes [Bug #22074].

Co-authored-by: Codex <199175422+chatgpt-connector[bot]@users.noreply.github.com>
Add ClassExact and ClassSubclass bits to the HIR type lattice, with
Class = ClassExact | ClassSubclass. Remove the special-case dispatch
on RUBY_T_CLASS and RUBY_T_MODULE in from_value; classification now
flows through the standard exact/subclass class lookup, so e.g.
Kernel (whose class_of returns its singleton class) is recognized as
ModuleSubclass rather than ModuleExact.
Try resolve_receiver_type_from_profile first and only fall back to the
runtime exact class from the static type when no profile is available.
Profile data carries shape information that the static type lacks, and
duplicate guards can generally be eliminated downstream.
* ZJIT: Fix exit tracing so that recompiles still happen

Before this commit, exit tracing would not allow recompiles to happen.
Exit tracing works by installing custom exit handlers in order to trace
exit locations.  Recompilation also works by installing custom exit
handlers.  Exit tracing didn't take in to account that the particular
exit might want to recompile, so recompiles weren't happening when exit
tracing was enabled.

We can see the consequences with the following code:

```ruby
class C
  def initialize(extra)
    @attribute_types = nil
    @A = 1 if extra >= 1
    @b = 1 if extra >= 2
  end

  def attribute_types
    @attribute_types ||= 123
  end
end

a = C.new(1)
b = C.new(2)
c = C.new(0)

5_000.times { a.attribute_types }

50_000.times do
  b.attribute_types
  c.attribute_types
end
```

The `attribute_types` method is initially compiled as a monomorphic ivar
read.  We expect recompilation to occur and it _should_ get recompiled
as a polymorphic ivar read.

Before this patch, if you run miniruby like this:

```
./miniruby --zjit --zjit-trace-compiles --zjit-trace-exits --zjit-trace-invalidation --zjit-dump-hir --zjit-max-versions=10 test.rb
```

The output HIR will be like this (I've omitted a bunch of BBs to make
it readable):

```
Optimized HIR:
fn attribute_types@../test.rb:9:
bb3(v6:BasicObject):
  PatchPoint SingleRactorMode
  v36:HeapBasicObject = GuardType v6, HeapBasicObject
  v37:CShape = LoadField v36, :shape_id@0x4
  v38:CShape[0x180009] = GuardBitEquals v37, CShape(0x180009)
  v39:BasicObject = LoadField v36, :@attribute_types@0x10
  CheckInterrupts
  v15:CBool = Test v39
  v16:Truthy = RefineType v39, Truthy
  CondBranch v15, bb4(v36, v16), bb5()

Optimized HIR:
fn attribute_types@../test.rb:9:
bb3(v6:BasicObject):
  PatchPoint SingleRactorMode
  v36:HeapBasicObject = GuardType v6, HeapBasicObject
  v37:CShape = LoadField v36, :shape_id@0x4
  v38:CShape[0x180009] = GuardBitEquals v37, CShape(0x180009)
  v39:BasicObject = LoadField v36, :@attribute_types@0x10
  CheckInterrupts
  v15:CBool = Test v39
  v16:Truthy = RefineType v39, Truthy
  CondBranch v15, bb4(v36, v16), bb5()
```

Note that the `attribute_types` method stays monomorphic.

After this patch, the HIR looks like this:

```
Optimized HIR:
fn attribute_types@../test.rb:9:
bb3(v6:BasicObject):
  PatchPoint SingleRactorMode
  v36:HeapBasicObject = GuardType v6, HeapBasicObject
  v37:CShape = LoadField v36, :shape_id@0x4
  v38:CShape[0x180009] = GuardBitEquals v37, CShape(0x180009) recompile
  v39:BasicObject = LoadField v36, :@attribute_types@0x10
  CheckInterrupts
  v15:CBool = Test v39
  v16:Truthy = RefineType v39, Truthy
  CondBranch v15, bb4(v36, v16), bb5()

Optimized HIR:
fn attribute_types@../test.rb:9:
bb3(v6:BasicObject):
  PatchPoint SingleRactorMode
  v11:HeapBasicObject = GuardType v6, HeapBasicObject
  v12:CUInt64 = LoadField v11, :RBASIC_FLAGS@0x0
  v14:CUInt64[0xffffffff0000001f] = Const CUInt64(0xffffffff0000001f)
  v15:CPtr[CPtr(0x18000900000001)] = Const CPtr(0x18000900000001)
  v16 = RefineType v15, CUInt64
  v17:CInt64 = IntAnd v12, v14
  v18:CBool = IsBitEqual v17, v16
  CondBranch v18, bb6(), bb7()
bb7():
  v22:CUInt64[0xffffffff0000001f] = Const CUInt64(0xffffffff0000001f)
  v23:CPtr[CPtr(0x18000a00000001)] = Const CPtr(0x18000a00000001)
  v24 = RefineType v23, CUInt64
  v25:CInt64 = IntAnd v12, v22
  v26:CBool = IsBitEqual v25, v24
  CondBranch v26, bb8(), bb9()
bb9():
  v30:CUInt64[0xffffffff0000001f] = Const CUInt64(0xffffffff0000001f)
  v31:CPtr[CPtr(0x18000800000001)] = Const CPtr(0x18000800000001)
  v32 = RefineType v31, CUInt64
  v33:CInt64 = IntAnd v12, v30
  v34:CBool = IsBitEqual v33, v32
  CondBranch v34, bb10(), bb11()
```

You can see it's polymorphic now

* Pull compile_exit in to compile_exit_body

This way we can share implementation between normal exit compilation and
when we need to record exits

* update comment
@pull pull Bot locked and limited conversation to collaborators May 22, 2026
@pull pull Bot added the ⤵️ pull label May 22, 2026
@pull pull Bot merged commit 7012f36 into turkdevops:master May 22, 2026
0 of 2 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants